package com.qd.system.service.org;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cdqidi.constant.ConstantDto;
import com.cdqidi.db.BaseService;
import com.cdqidi.dto.ApiResult;
import com.cdqidi.dto.ApiResultWrapper;
import com.cdqidi.dto.CacheKey;
import com.cdqidi.excel.ExcelExport;
import com.cdqidi.excel.util.ExportPage;
import com.cdqidi.exception.ApiException;
import com.cdqidi.util.RedisTemplateUtil;
import com.qd.common.sys.constant.Constants;
import com.qd.common.sys.domain.entity.org.OrgDTO;
import com.qd.common.sys.domain.tree.TreeSelect;
import com.qd.system.mapper.OrgMapper;
import com.qd.system.model.Org;
import com.qd.system.service.dict.MbUtil;
import com.qd.system.service.user.UserOperatorService;
import com.qd.system.treecl.TreeClDTO;
import com.qd.system.treecl.TreeClService;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

/**
 * @author sjk
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class OrgService extends BaseService<OrgMapper, Org> {

    private static final String PREFIX_ID = "sys_org_orgId_{0}";
    private final RedisTemplateUtil<Org> redisTemplateUtil;
    @Getter
    private final TreeClService treeClService;
    private final HttpServletResponse response;

    /**
     * 保存
     *
     * @param dto 页面对象
     * @return 页面对象
     */
    @Transactional(rollbackFor = Exception.class)
    public OrgDTO save(OrgDTO dto) {
        final Org model = dtoToModel(dto);
        try {
            if (super.save(model)) {
                return modelToDto(model);
            }
            throw new ApiException("添加失败");
        } finally {
            clearCache(model);
            model.freeData();
        }
    }

    /**
     * 修改
     *
     * @param dto 页面对象
     * @return 页面对象
     */
    @Transactional(rollbackFor = Exception.class)
    public OrgDTO update(OrgDTO dto) {
        final Org historyModel = Optional.ofNullable(getById(dto.getOrgId())).orElseThrow(() -> new ApiException("ID不存在,不能更新"));
        final Org model = dtoToModel(dto);
        try {
            if (super.updateById(model)) {
                return modelToDto(model);
            }
            throw new ApiException("更新失败");
        } finally {
            clearCache(historyModel);
            historyModel.freeData();
            model.freeData();
        }
    }

    /**
     * 批量添加
     *
     * @param mList 数据库对象
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveBatch(List<Org> mList) throws ApiException {
        try {
            if (!super.saveBatch(mList)) {
                throw new ApiException("批量添加失败");
            }
        } finally {
            clearCaches(mList);
        }
    }

    /**
     * 批量更新
     *
     * @param mList 数据库对象
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateBatchIds(List<Org> mList) {
        final List<String> ids = mList.stream().map(Org::getOrgId).collect(toList());
        final List<Org> historyModelList = checkIds(ids);
        try {
            if (!super.updateBatchById(mList)) {
                throw new ApiException("批量更新失败");
            }
        } finally {
            clearCaches(historyModelList);
            historyModelList.clear();
            ids.clear();
        }
    }

    /**
     * 删除，单个
     *
     * @param orgId 主键
     */
    @Transactional(rollbackFor = Exception.class)
    public void removeById(String orgId) {
        final Org model = Optional.ofNullable(getById(orgId)).orElseThrow(() -> new ApiException("数据不存在,不能删除"));
        try {
            if (!super.removeById(orgId)) {
                throw new ApiException("删除失败");
            }
        } finally {
            clearCache(model);
            model.freeData();
        }
    }

    /**
     * 根据主键判断数据是否存在
     *
     * @param orgId 主键
     * @return 存在为true
     */
    @Transactional(readOnly = true)
    public Boolean isExistsById(String orgId) {
        boolean exists = false;
        if (StringUtils.hasLength(orgId)) {
            final Org model = getById(orgId);
            exists = (null != model);
            if (exists) {
                model.freeData();
            }
        }
        return exists;
    }

    /**
     * 判断父级ID是否存在
     *
     * @param parentId 父级ID
     * @return 存在为true
     */
    public Boolean isExistsByParentId(String parentId) {
        if (StringUtils.hasLength(parentId)) {
            final QueryWrapper<Org> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("parent_id", parentId);
            return super.count(queryWrapper) > 0;
        }
        return false;
    }

    /**
     * 根据主键获取数据
     *
     * @param orgId 主键
     * @return 单条记录
     */
    @Transactional(readOnly = true)
    public Org getById(String orgId) {
        final String key = RedisTemplateUtil.getRedisCacheKey(PREFIX_ID, orgId);
        return redisTemplateUtil.get(new CacheKey().setKey(key).setTimeout(ConstantDto.REDIS_TIME_OUT_DAY), () -> super.getById(orgId), Org.class);
    }

    /**
     * 根据主键获取数据
     *
     * @param orgId 主键
     * @return 单条记录，转换成页面对象
     */
    @Transactional(readOnly = true)
    public OrgDTO getByIdDto(String orgId) {
        final Org model = getById(orgId);
        if (null != model) {
            return modelToDto(model);
        }
        return null;
    }

    /**
     * 根据条件查询单条数据
     *
     * @param dto 查询参数
     * @return 单条记录
     */
    @Transactional(readOnly = true)
    public Org getOne(OrgDTO dto) {
        final QueryWrapper<Org> queryWrapper = createQueryWrapper(dto);
        final Org model = super.getOne(queryWrapper);
        queryWrapper.clear();
        return model;
    }

    /**
     * 根据条件查询单条数据
     *
     * @param dto 查询参数
     * @return 单条记录，转换成页面对象
     */
    @Transactional(readOnly = true)
    public OrgDTO getOneDto(OrgDTO dto) {
        final Org model = getOne(dto);
        if (null == model) {
            return null;
        }
        final OrgDTO newDto = modelToDto(model);
        model.freeData();
        return newDto;
    }

    /**
     * 根据条件查询列表数据
     *
     * @param dto 查询参数
     * @return 列表数据
     */
    @Transactional(readOnly = true)
    public List<Org> getList(OrgDTO dto) {
        final QueryWrapper<Org> queryWrapper = createQueryWrapper(dto);
        final List<Org> list = super.list(queryWrapper);
        queryWrapper.clear();
        return list;
    }

    /**
     * 根据条件查询列表数据
     *
     * @param dto 查询参数
     * @return 列表数据，转换成页面对象
     */
    @Transactional(readOnly = true)
    public List<OrgDTO> getListDto(OrgDTO dto) {
        return modelToDtoList(getList(dto));
    }

    /**
     * 分页数据
     *
     * @param page 分页对象
     * @param dto  查询参数
     * @return 分页信息
     */
    @Transactional(readOnly = true)
    public IPage<OrgDTO> page(Page<Org> page, OrgDTO dto) {
        QueryWrapper<Org> queryWrapper = createQueryWrapper(dto, "org.");
        if (StringUtils.hasLength(dto.getParentId())) {
            queryWrapper.eq("org.parent_id", dto.getParentId());
        }
        return baseMapper.page(page, queryWrapper);
    }

    /**
     * 导出Excel
     *
     * @param query 查询条件
     * @throws IOException 异常
     */
    @Transactional(readOnly = true)
    public void export(OrgDTO query) throws IOException {
        final ExportPage<Org, OrgDTO> exportPage = new ExportPage<>();
        try {
            final List<OrgDTO> list = exportPage.getAllForPage(page -> page(page, query).getRecords());
            try {
                final Map<String, List<OrgDTO>> collect = list.stream().collect(Collectors.groupingBy(OrgDTO::getOrgId));
                collect.forEach((key, value) -> {
                    if (value.size() > 1) {
                        log.info("key: " + key);
                    }
                });
                ExcelExport.downloadExcel(response, OrgDTO.class, () -> list);
            } catch (IOException e) {
                log.error("导出失败", e);
                throw new ApiException("导出失败");
            }
        } finally {
            exportPage.freeData();
        }

    }

    /**
     * 清空缓存
     *
     * @param model 数据库对象
     */
    public void clearCache(Org model) {
        if (null == model) {
            return;
        }
        redisTemplateUtil.deleteByKey(RedisTemplateUtil.getRedisCacheKey(PREFIX_ID, model.getOrgId()));
    }

    /**
     * 批量清空缓存
     *
     * @param list 数据库对象
     */
    public void clearCaches(List<Org> list) {
        if (null == list || list.isEmpty()) {
            return;
        }
        List<String> ids = list.stream().map(model -> RedisTemplateUtil.getRedisCacheKey(PREFIX_ID, model.getOrgId())).collect(toList());
        if (!ids.isEmpty()) {
            redisTemplateUtil.deleteByKey(ids);
            ids.clear();
        }
    }

    /**
     * 数据库对象转页面对象
     *
     * @param model 数据库对象
     * @return 页面对象
     */
    @Transactional(readOnly = true)
    public OrgDTO modelToDto(Org model) {
        if (null == model) {
            return null;
        }
        final OrgDTO dto = new OrgDTO();
        dto.setOrgId(model.getOrgId());
        dto.setParentId(model.getParentId());
        dto.setOrgName(model.getOrgName());
        dto.setOrderNum(model.getOrderNum());
        dto.setLeader(model.getLeader());
        dto.setContacts(model.getContacts());
        dto.setContactsPhone(model.getContactsPhone());
        dto.setEmail(model.getEmail());
        dto.setWebsite(model.getWebsite());
        dto.setAddress(model.getAddress());
        dto.setRemark(model.getRemark());
        dto.setOrgStatus(model.getOrgStatus());
        dto.setAddTime(model.getAddTime());
        dto.setUpdateTime(model.getUpdateTime());
        buildDisplay(dto);
        return dto;
    }

    /**
     * 页面对象转数据库对象
     *
     * @param dto 页面对象
     * @return 数据库对象
     */
    public Org dtoToModel(OrgDTO dto) {
        if (null == dto) {
            return null;
        }
        final Org model = new Org();
        model.setOrgId(dto.getOrgId());
        model.setParentId(dto.getParentId());
        model.setOrgName(dto.getOrgName());
        model.setOrderNum(dto.getOrderNum());
        model.setLeader(dto.getLeader());
        model.setContacts(dto.getContacts());
        model.setContactsPhone(dto.getContactsPhone());
        model.setEmail(dto.getEmail());
        model.setWebsite(dto.getWebsite());
        model.setAddress(dto.getAddress());
        model.setRemark(dto.getRemark());
        model.setOrgStatus(dto.getOrgStatus());
        model.setAddTime(dto.getAddTime());
        model.setUpdateTime(dto.getUpdateTime());
        return model;
    }

    /**
     * 码表转换
     *
     * @param dto 页面对象
     */
    @Transactional(readOnly = true)
    public void buildDisplay(OrgDTO dto) {
        dto.setOrgStatusDisplay(MbUtil.idToDisplay(dto.getOrgStatus()));
        if (StringUtils.hasLength(dto.getParentId()) && !dto.getParentId().equals(Constants.DEFAULT_TREE_PARENT_ID)) {
            dto.setParentIdDisplay(idToDisplay(dto.getParentId()));
        }
    }

    /**
     * 数据库对象转页面对象
     *
     * @param list 数据库对象
     * @return 页面对象
     */
    public List<OrgDTO> modelToDtoList(List<Org> list) {
        if (null == list) {
            return Collections.emptyList();
        }
        return list.stream().map(this::modelToDto).collect(toList());
    }

    /**
     * 页面对象转数据库对象
     *
     * @param list 页面对象
     * @return 数据库对象
     */
    public List<Org> dtoToModelList(List<OrgDTO> list) {
        if (null == list) {
            return Collections.emptyList();
        }
        return list.stream().map(this::dtoToModel).collect(toList());
    }

    /**
     * 拼装查询参数，除了主键的其他字段会自动加入进来
     *
     * @param dto 查询参数，不为空的属性会被自动加入
     */
    public QueryWrapper<Org> createQueryWrapper(OrgDTO dto) {
        return createQueryWrapper(dto, "");
    }

    /**
     * 拼装查询参数，除了主键的其他字段会自动加入进来
     *
     * @param dto        查询参数，不为空的属性会被自动加入
     * @param tableAlias 表别名
     */
    public QueryWrapper<Org> createQueryWrapper(OrgDTO dto, String tableAlias) {
        final QueryWrapper<Org> queryWrapper = new QueryWrapper<>();
        if (null != dto) {
            if (StringUtils.hasLength(tableAlias) && tableAlias.charAt(tableAlias.length() - 1) != '.') {
                tableAlias += ".";
            }
            if (StringUtils.hasLength(dto.getOrgName())) {
                queryWrapper.like(tableAlias + "org_name", dto.getOrgName());
            }
            if (StringUtils.hasLength(dto.getLeader())) {
                queryWrapper.eq(tableAlias + "leader", dto.getLeader());
            }
            if (StringUtils.hasLength(dto.getContacts())) {
                queryWrapper.eq(tableAlias + "contacts", dto.getContacts());
            }
            if (StringUtils.hasLength(dto.getContactsPhone())) {
                queryWrapper.eq(tableAlias + "contacts_phone", dto.getContactsPhone());
            }
            if (StringUtils.hasLength(dto.getAddress())) {
                queryWrapper.like(tableAlias + "address", dto.getAddress());
            }
            if (null != dto.getOrgStatus()) {
                queryWrapper.eq(tableAlias + "org_status", dto.getOrgStatus());
            }
            if (StringUtils.hasLength(dto.getBeginTime())) {
                queryWrapper.apply("date_format(" + tableAlias + "add_time,'%Y-%m-%d') >= {0}", dto.getBeginTime());
            }
            if (StringUtils.hasLength(dto.getEndTime())) {
                queryWrapper.apply("date_format(" + tableAlias + "add_time,'%Y-%m-%d') <= {0}", dto.getEndTime());
            }
            UserOperatorService.buildInSql(dto, queryWrapper);
        }
        queryWrapper.orderByAsc(tableAlias + "parent_id");
        queryWrapper.orderByAsc(tableAlias + "order_num");
//        queryWrapper.groupBy(tableAlias + "org_id");
        return queryWrapper;
    }

    /**
     * 批量检查主键在数据库中是否存在
     *
     * @param ids 主键集合
     * @return 主键查询出来的集合
     */
    public List<Org> checkIds(List<String> ids) {
        if (null == ids || ids.isEmpty()) {
            throw new ApiException("机构ID不能为空");
        }
        final List<Org> list = super.listByIds(ids);
        if (list.isEmpty()) {
            throw new ApiException("机构ID不存在" + Arrays.toString(ids.toArray()));
        }
        if (ids.size() == list.size()) {
            return list;
        }
        List<String> dbIds = list.stream().map(Org::getOrgId).collect(toList());
        final List<String> notExistsList = ids.stream().filter(id -> !dbIds.contains(id)).collect(toList());
        dbIds.clear();
        if (!notExistsList.isEmpty()) {
            throw new ApiException("机构ID不存在" + Arrays.toString(notExistsList.toArray()));
        }
        return list;
    }

    /**
     * 判断id是否存在
     *
     * @param id 主键
     */
    @Transactional(readOnly = true)
    public void checkId(String id) {
        if (Boolean.FALSE.equals(isExistsById(id))) {
            throw new ApiException("机构ID不存在[" + id + "]");
        }
    }

    /**
     * 树形选择器
     *
     * @param orgDTO 参数
     * @return 树形结构
     */
    @Transactional(readOnly = true)
    public List<Object> treeSelect(OrgDTO orgDTO) {
        long startTime = System.currentTimeMillis();
        final List<OrgDTO> orgList = selectOrgList(orgDTO);
        long endTime = System.currentTimeMillis();
        log.info("orgList耗时: " + (endTime - startTime) + "ms");
        startTime = endTime;
        try {
            final List<OrgDTO> orgTrees = buildOrgTree(orgList);
            if (StringUtils.hasLength(orgDTO.getParentId())) {
                //延时加载，此时只需要显示是否有下级，不需要显示下级的属性
                return orgTrees.stream().map(cl -> new TreeSelect(cl).buildMap()).collect(toList());
            }
            //显示children
            return orgTrees.stream().map(TreeSelect::new).collect(toList());
        } finally {
            endTime = System.currentTimeMillis();
            log.info("耗时： " + (endTime - startTime) + "ms");
        }

    }

    /**
     * 根据组织机构ID获得组织机构名字
     *
     * @param orgId 组织机构ID
     * @return 组织机构名字
     */
    @Transactional(readOnly = true)
    public String idToDisplay(String orgId) {
        String orgName = "";
        if (StringUtils.hasLength(orgId)) {
            final Org org = getById(orgId);
            orgName = (null == org ? "" : org.getOrgName());
        }
        return orgName;
    }

    /**
     * 创建树形结构对象
     *
     * @return 树形结构
     */
    public TreeClDTO buildTreeClDto() {
        return new TreeClDTO("sys_org").setTableColumnId("org_id").setTableColumnName("org_name");
    }

    /**
     * 判断组织机构名字是否存在
     *
     * @param orgDTO 按orgName查询
     * @return 存在为true
     */
    public boolean checkOrgNameUnique(OrgDTO orgDTO) {
        final OrgDTO query = new OrgDTO();
        query.setOrgName(orgDTO.getOrgName());
        final QueryWrapper<Org> queryWrapper = createQueryWrapper(query);
        boolean isExists;
        Org org = getOne(queryWrapper, false);
        if (null == org) {
            isExists = false;
        } else {
            if (StringUtils.hasLength(org.getOrgId())) {
                isExists = !org.getOrgId().equals(orgDTO.getOrgId());
            } else {
                isExists = true;
            }
            org.freeData();
        }
        query.freeData();
        queryWrapper.clear();
        return isExists;
    }

    /**
     * 保存组织机构信息
     *
     * @param orgDTO 机构信息
     * @return true or false
     */
    @Transactional(rollbackFor = Exception.class)
    public ApiResultWrapper<Object> saveOrg(OrgDTO orgDTO) {
//        if (checkOrgNameUnique(orgDTO)) {
//            return ApiResult.error("组织机构名称已经存在");
//        }
        if (!orgDTO.getParentId().equals(Constants.DEFAULT_TREE_PARENT_ID)) {
            final Org org = getById(orgDTO.getParentId());
            if (null == org) {
                return ApiResult.error("父级机构信息不存在");
            }
            org.freeData();
        }
        checkMb(orgDTO);
        orgDTO.setAddTime(LocalDateTime.now());
        final OrgDTO saveOrg = save(orgDTO);
        final TreeClDTO treeClDto = buildTreeClDto().setParam(saveOrg.getOrgId());
        treeClService.add(treeClDto);
        treeClDto.freeData();
        return ApiResult.success(saveOrg);
    }

    /**
     * 修改组织信息
     *
     * @param orgDTO 机构信息
     * @return 成功 or 失败
     */
    @Transactional(rollbackFor = Exception.class)
    public ApiResultWrapper<Object> updateOrg(OrgDTO orgDTO) {
        boolean isUpdate = true;
        final String parentId = orgDTO.getParentId();
        final Org org = getById(orgDTO.getOrgId());
        if (null == org) {
            return ApiResult.error("组织机构信息不存在");
        }
        if (!org.getParentId().equals(parentId)) {
            //父级部门发生变化，执行移动cl操作
            isUpdate = false;
        }
        org.freeData();
        if (!parentId.equals(Constants.DEFAULT_TREE_PARENT_ID)) {
            if (Boolean.FALSE.equals(isExistsById(parentId))) {
                return ApiResult.error("父级组织机构信息不存在");
            }
        }
        checkMb(orgDTO);
        update(orgDTO);
        final TreeClDTO treeClDto = buildTreeClDto().setParam(orgDTO.getOrgId());
        if (isUpdate) {
            treeClService.update(treeClDto);
        } else {
            treeClService.move(treeClDto);
        }
        treeClDto.freeData();
        treeClDto.freeData();
        return ApiResult.success("更新成功");
    }

    /**
     * 移动组织
     *
     * @param orgDTO 查询参数
     * @return 成功 or 失败
     */
    @Transactional(rollbackFor = Exception.class)
    public ApiResultWrapper<Object> moveOrg(OrgDTO orgDTO) {
        if (Boolean.FALSE.equals(isExistsById(orgDTO.getOrgId()))) {
            return ApiResult.error("组织机构信息不存在");
        }
        if (!orgDTO.getParentId().equals(Constants.DEFAULT_TREE_PARENT_ID)) {
            if (Boolean.FALSE.equals(isExistsById(orgDTO.getParentId()))) {
                return ApiResult.error("父级组织机构信息不存在");
            }
        }
        update(orgDTO);
        final TreeClDTO treeClDto = buildTreeClDto().setParam(orgDTO.getOrgId());
        treeClService.move(treeClDto);
        orgDTO.freeData();
        treeClDto.freeData();
        return ApiResult.success("移动成功");
    }

    /**
     * 检查码表信息是否正确
     *
     * @param orgDTO 前端对象
     */
    private void checkMb(OrgDTO orgDTO) {
        if (null != orgDTO.getOrgStatus()) {
            if (!MbUtil.isExists(orgDTO.getOrgStatus())) {
                throw new ApiException("组织机构状态码错误");
            }
        }
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<OrgDTO> list, OrgDTO orgDTO) {
        return !getChildList(list, orgDTO).isEmpty();
    }

    /**
     * 得到子节点列表
     *
     * @param list   整棵树
     * @param orgDTO 父级ID
     * @return 父级ID下面的数据
     */
    private List<OrgDTO> getChildList(List<OrgDTO> list, OrgDTO orgDTO) {
        return list.stream().filter(org -> StringUtils.hasLength(org.getParentId()) && org.getParentId().equals(orgDTO.getOrgId())).collect(toList());
    }

    /**
     * 查询机构列表
     *
     * @param orgDTO 查询条件
     * @return 列表数据
     */
    public List<OrgDTO> selectOrgList(OrgDTO orgDTO) {
        final QueryWrapper<Org> queryWrapper = new QueryWrapper<>();
        if (StringUtils.hasLength(orgDTO.getParentId())) {
//            if (!OrgDTO.getParentId().equals(Constants.DEFAULT_TREE_PARENT_ID)) {
            queryWrapper.eq("cl.parent_id", orgDTO.getParentId());
            //用的是延时加载，只查询自己和自己的下一级
            queryWrapper.lt("cl.distance", 3);
//            }
        } else {
            queryWrapper.groupBy("org.org_id");
        }
        UserOperatorService.buildInSql(orgDTO, queryWrapper);
        queryWrapper.orderByAsc("org.parent_id");
        queryWrapper.orderByAsc("org.order_num");

        final List<OrgDTO> list = baseMapper.getList(queryWrapper);
        queryWrapper.clear();
        return list;
    }

    /**
     * 构建前端所需要树结构
     *
     * @param orgList 机构列表
     * @return 树结构列表
     */
    public List<OrgDTO> buildOrgTree(List<OrgDTO> orgList) {
        List<OrgDTO> returnList = new ArrayList<>();
        final List<String> tempList = orgList.stream().map(OrgDTO::getOrgId).collect(toList());
        for (OrgDTO org : orgList) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(org.getParentId())) {
                recursionFn(orgList, org);
                returnList.add(org);
            }
        }
        if (returnList.isEmpty()) {
            returnList = orgList;
        }
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list   树形结构列表
     * @param orgDTO 查询参数
     */
    private void recursionFn(List<OrgDTO> list, OrgDTO orgDTO) {
        // 得到子节点列表
        final List<OrgDTO> childList = getChildList(list, orgDTO);
        orgDTO.setChildren(childList);
        for (OrgDTO tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    public void isValidOrg(List<String> existsOrgIds, String orgId, List<String> errors) {
        if (StringUtils.hasLength(orgId)) {
            if (!existsOrgIds.contains(orgId)) {
                errors.add("机构ID不存在[" + orgId + "]");
            }
        }
    }

    /**
     * 根据名字查询组织ID
     * @param nameList 名字列表
     * @return 机构列表
     */
    @Transactional(readOnly = true)
    public List<Org> listByOrgNames(List<String> nameList) {
        QueryWrapper<Org> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("org_name", nameList);
        return getBaseMapper().selectList(queryWrapper);
    }
}